network: Clear connectivity queue after portal login
When full connectivity (or rather, non-portal connectivity) is achieved,
we can clear all active portal helpers.
Normally, the portal helper will signal that it is done, but it is
implemented in a racy manner. So here let's do a comprehensive big
hammer solution to guarantee the portal helper definitely gets
eventually closed even if we miss the race window in the portal helper.
(The race is: the portal helper checks connectivity status either
immediately or within a certain amount of time after a navigation policy
decision. This could theoretically be too soon, and if missed, it won't
be rescheduled.)
portalHelper: Add extra check for policy decision type
This check will always be true currently, because there are only three
possible types of policy decisions, and both of the others are already
handled above. But if new policy decision types are ever added in the
future, then we probably don't want to execute this code.
portalHelper: Reduce the connectivity check rate limit
30 seconds is much too long for GNOME Shell to notice that full
connectivity has been achieved. The portal helper is expected to be
closed once connectivity is achieved.
Note this does NOT mean we unconditionally spam the connectivity check
server every 5 seconds. A connectivity check is still only scheduled
when an actual navigation occurs.
portalHelper: Schedule recheck if it's too soon to recheck
Currently we have a 30 second limit on rechecks. A recheck that would
violate the limit is simply dropped. This causes the portal helper to
never close itself.
Instead, schedule a future recheck for as soon as the timeout expires.
This will put an upper bound on how long the portal helper will
unnecessarily remain open.
(I've also changed the logic to unconditionally emit CANCELLED in
vfunc_close_request(), since this seems more correct. This won't
actually affect anything, because gnome-shell just ignores the
CANCELLED status, but in theory it's nice to end things with an
indication that we are finished. Otherwise, CANCELLED will never be
emitted.)
Sebastian Wick [Sat, 21 Jun 2025 22:12:09 +0000 (00:12 +0200)]
shellDBus: Add the Shell.Brightness interface
This lets gnome-settings-daemon control dimming for power saving, and
set a auto brightness target for brightness sensors. This finally let's
us drop direct backlight control from g-s-d.
Sebastian Wick [Sat, 21 Jun 2025 22:10:04 +0000 (00:10 +0200)]
brightnessManager: Add keyboard shortcuts for monitor brightness control
This used to be done by g-s-d but to avoid the split brain situation,
g-s-d has to stop poking at the backlight directly. This also means that
there is no reason to round-trip through g-s-d anymore, and we can just
implement the shortcuts in gnome shell.
This also adds new shortcuts for controling the backlight of the "active
monitor" (i.e. the one with the cursor) by pressing shift as well.
Sebastian Wick [Sat, 21 Jun 2025 22:07:50 +0000 (00:07 +0200)]
status/brightness: Handle multiple monitors
The BrightnessManager exposes a global scale and per monitor scales
which we can also hook up to give users control over individual monitor
brightnesses. If there are more than one controllable backlight, the
brightness slider in quick settings becomes expandable and shows a
slider for each monitor with controllable backlight.
Sebastian Wick [Sat, 21 Jun 2025 22:06:27 +0000 (00:06 +0200)]
brightnessManager: Handle dimming and auto brightness
We don't want gnome-settings-daemon to poke directly at mutters
backlight anymore because that would be a split brain situation where
g-s and g-s-d will fight with each other. This implements a way to tell
the BrightnessManager to dim the screen and set an auto brightness
target, and the manager will set the backlight accordingly.
Sebastian Wick [Sat, 21 Jun 2025 22:17:11 +0000 (00:17 +0200)]
status/brightness: Switch to the new BrightnessManager
Instead of looking at the monitor backlights directly, connect to the
BrightnessManager global scales. Everything should continue working as
before, this simply gives the BrightnessManager control over the actual
backlight with the quick settings brightness sliders being one input.
This implements a backlight manager which creates a global and multiple
per monitor BrightnessScales and updates the backlight based on the
BrightnessScales changing and the backlight changing. It shows the OSD
in response to changes.
In the future it will also handle dimming, auto brightness and keyboard
shortcuts.
The idea is that the per monitor scale changes the ratio between monitor
brighnesses and the global scale scales the monitor brightnesses
accordingly.
Sebastian Wick [Wed, 2 Jul 2025 10:23:51 +0000 (12:23 +0200)]
osdWindow: Take per-monitor information in show and add showAll, showOne
The current API only supports showing an OSD on all monitors or on one
monitor. This change makes it possible to show the OSD on any
combination of monitors while providing simpler functions for the common
usages.
It still retains the single-event character and cancels previous OSDs on
unaffected monitors.
We will require this for the screen brightness keyboard shortcuts in the
future.
Florian Müllner [Thu, 22 May 2025 02:26:19 +0000 (04:26 +0200)]
dbusServices/extensions: Stop using an expander for error details
Always show the error details up front instead of hiding them in an
expander. Other then getting rid of custom widgetry, this solves
the awkwardness of switching between very little content (which
is best suited by a small window size) to very verbose content
(which favors a tall window).
Florian Müllner [Thu, 22 May 2025 01:27:51 +0000 (03:27 +0200)]
dbusServices/extensions: Use regular constructors
Regular constructors have worked for GObject subclasses for a couple
of years now. While there is no functional difference to _init(),
it's simply nicer to use the same syntax for all classes, so quickly
change that before doing further changes.
Jonas Dreßler [Sat, 5 Nov 2022 21:36:47 +0000 (22:36 +0100)]
Connect to DnD signals using connectObject()
Currently DnD uses `disconnectAll()` in a `::destroy` signal handler for
the drag actor. This is a little weird, as usually the connecting object
is in charge of disconnecting as well.
Since we have some nice convenience API for this nowadays, use
`connectObject()` when connecting to DnD signals in the various draggable
actors that we have, which ensures the signal is disconnected as soon as
the draggable actors get destroyed.
This allows removing the call to `disconnectAll()` in DnD.
Jonas Dreßler [Thu, 24 Jul 2025 23:30:29 +0000 (01:30 +0200)]
smartcardManager: Properly disconnect signal connections from tokens
The `token.disconnectAll()` call here is not going to work: The method is
provided by gjs as convenience for native JS objects (added to an object
using `Signals.addSignalMethods()`). The token here meanwhile is a GObject,
which doesn't have a `disconnectAll()` method.
To make it (hopefully) work as intended, use the convenience functions
that we actually do add to GObjects, that is `connectObject()` and
`disconnectObject()`.
Jonas Dreßler [Mon, 24 Jul 2023 20:22:49 +0000 (22:22 +0200)]
appDisplay: Set popup menu side via parameter to AppIcon class
Let's make the "side" argument to the popupMenu() function for app icons
a param to the AppIcon class itself. The side is not that dynamic that it
needs to be defined on calling of the function, instead it can be defined
on creation of the AppIcon as well.
Sebastian Keller [Wed, 30 Jul 2025 13:24:29 +0000 (15:24 +0200)]
slider: Don't preserve paths after filling
Prior to 6fd0aac86 the paths were preserved when filling to allow
stroking the path afterwards. The stroke() then would have cleared the
path. Then when the stroking was dropped in that commit, a second fill()
call, this time without preserving the path was added, but missed from
the end arc of the bar level. This then would leak the path to the
slider handle.
Fix this by always using fill() instead of fillPreserve().
Florian Müllner [Tue, 10 Jun 2025 01:11:05 +0000 (03:11 +0200)]
tools: Switch to flat config for eslint
Both the .json and .yml config formats are deprecated in favor
of flat configs exported from eslint.config.js files.
The good news is that gjs' config is now available as a shared
config from the `eslint-config-gnome` package in World/javascript,
so we no longer have to copy the entire thing.
Florian Müllner [Tue, 10 Jun 2025 00:36:50 +0000 (02:36 +0200)]
tools: Add run-eslint.sh script
The script is a small wrapper around the `ci-run-eslint` package
from World/javascript, which is a generalized and improved version
of the .gitlab-ci/run-eslint script we are currently using.
It only requires `npm` to be available, so it simplifies running
eslint locally quite a lot.
magnifier: Scale the sprite to match the current monitor scaling
Compute the sprite texture scale (unfortunately using a workaround, based on
mutter cursor size preferences, tying to figure out the closest texture integer
scaling), and use this value to compute the scaling that should be applied to
the sprite in order to match the current monitor scaling.
ci: Install dependencies when using custom destdir
Commit fd4320156c9 changed the `update-mutter` command inside the
toolbox to also install into the sysext extension dir, so people
who don't build mutter themselves can still use the sysext tooling.
Except they can't, because additional dependencies from mutter's
install-common-dependencies.sh script are missing as the script
is currently only invoked by the meson-build script.
Fix that by also running the script when running install-meson-project
with a destdir, as is done from the update-mutter command.
gnome-session is no longer a service manager, and thus doesn't need to
be notified of our readiness like this. We now do this exclusively
through systemd
screenshot: Fix taking interactive screenshots via D-Bus
The D-Bus method relies on the `screenshot-taken` and `closed` signals
to differentiate successful operations from canceled/failed ones.
However as the `screenshot-taken` signal is emitted asynchronously,
it may end up being emitted after the `closed` signal even in case
of success. Await the result to ensure correct ordering.
The intermediate container allows the theme to control the distance
from the edge and spacing between buttons, which is more accessible
to the designers than computing the values from code.
loginDialog: Increase size of session/a11y buttons
The buttons on the login screen for the session and accessibility
menus can easily be lost, due to a combination of their size and
position, and the large amount of empty space.
network: Do not consider networks without ID as available
In some rare (and weird) cases network manager may provide us
connections without settings (since connection.get_settings() is
actually nullable, and this may lead to have a NULL connection ID, that
eventually breaks the network menu completely:
(gnome-shell:1579214): GNOME Shell-CRITICAL **: 20:27:14.874: Error:
Argument str2 may not be null
Now, despite that specific connection here has valid settings when
loaded from dbus, it may still happen that NM lib fails at other level in
fetching its settings.
That said, we should not fail if a connection has no settings, and
just skip it.
This was part of the original MxWidget import, but we never used
it for anything. After more than 15 years it is unlikely that we
are going to start, so remove it.
Carlos Garnacho [Sun, 29 Jun 2025 09:35:24 +0000 (11:35 +0200)]
screenShield: Fix pointer showing on motion
As an additional side effect of switching to the cursor visibility
inhibition API in the cursor tracker, there is no longer this
infighting in Mutter where pointer motion tries to set pointer
visibility on (since it's the last device used), and other places
wanting to inhibit it, such as the screenshield.
This resulted on the cursor wanting to show by itself, and somehow
trigger captured motion events on the ClutterStage. This no longer
happens, which results in the pointer staying hidden, seat unfocus
remaining uninhibited, and no motion events being sent in (since
the pointer device now does remain unfocused).
Fix this by:
- Setting a seat unfocus inhibition, so the pointer triggers motion
and focus despite being hidden
- Connecting to captured events on the screen lock group widget,
since captured events will respect the existing grab
This results in pointer motion again resulting on the cursor being
shown, when waking up the lockscreen.
Fixes: 91c6366e0 ("Adjust to cursor tracker visibility API changes")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3781>
Florian Müllner [Sun, 22 Jun 2025 12:59:07 +0000 (14:59 +0200)]
screenshot: Remove gnome-screenshot from allowed senders
It was removed from core after we got a built-in screenshot UI in
the shell, and is mostly unmaintained nowadays.
There is no good reason anymore for treating it differently than other
3rd-party screenshot tools, so stop giving it default access to the
private screenshotting API.
Florian Müllner [Sat, 7 Jun 2025 17:13:59 +0000 (19:13 +0200)]
loginDialog: Add a11y menu
When quick settings become configurable, users can add the a11y
toggles they need to the regular quick settings menu. This does
not really work for the login screen, where all a11y features
should be available by default.
Address this by adding a dedicated a11y menu button next to the
session menu button.
Florian Müllner [Sat, 7 Jun 2025 16:45:16 +0000 (18:45 +0200)]
status/accessibility: Export quick toggles
Implement quick toggles for every accessibility feature that is
currently exposed by the menu. Those toggles will eventually replace
the menu when quick setting become configurable.
However the login screen will use a dedicated accessibility menu
(once again), which does not depend on the quick settings feature,
so add the toggles now to allow implementing it.
It is a simple on/off control, which makes it a good fit for
quick settings. It also makes sense to expose the feature together
with other system controls, and while this somewhat removes the
control from the context of notifications, that doesn't seem to
be an issue on other platforms.
The control for enabling/disabling do-not-disturb will be moved into
quick settings. It makes sense to then also move the indicator, so stop
showing the do-not-disturb status in the top bar's messages indicator.
Instead, just hide the indicator altogether when do-not-disturb
is active.
Aligning the button to the end is a bit odd after removing the
do-not-disturb switch, so move it to the start instead and make
it pill-shaped to align better with the popover.